package de.hska.reka.websockets.client;

import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;

import org.springframework.stereotype.Component;
import org.xlightweb.IWebSocketConnection;
import org.xlightweb.WebSocketConnection;

import de.hska.reka.websockets.IWebSocketExporter;
import de.hska.reka.websockets.model.AbstractBeanField;

import javax.annotation.PostConstruct;

@SuppressWarnings("restriction")
@Component
public class WebSocketClientExporter implements IWebSocketExporter {
	private String serviceUrl;

	private HashMap<Class<?>, Object> proxyCache = new HashMap<Class<?>, Object>();
	private OneToOneInvokationHandler oneToOneInvokationHandler = new OneToOneInvokationHandler();

	public void setServiceUrl(String serviceUrl) {
		this.serviceUrl = serviceUrl;
		this.startConnection();
	}

	public String getServiceUrl() {
		return this.serviceUrl;
	}

	private void startConnection() {
		try {
			System.out.println("connecting to: " + "ws://"
					+ this.getServiceUrl());
			IWebSocketConnection connection = new WebSocketConnection("ws://"
					+ this.getServiceUrl());
			this.oneToOneInvokationHandler.setConnection(connection);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@PostConstruct
	public void postConstruct() {

	}

	public void addMethodToMap(Method method, String beanName) {
		// TODO Auto-generated method stub

	}

	public void addProxy(AbstractBeanField websocketController,
			Class<?> interfaceClass) {
		Object proxy = this.proxyCache.get(interfaceClass);
		if (proxy == null) {
			proxy = Proxy.newProxyInstance(interfaceClass.getClassLoader(),
					new Class<?>[] { interfaceClass },
					this.oneToOneInvokationHandler);
			this.proxyCache.put(interfaceClass, proxy);
		}
		this.setProxyOfBean(proxy, websocketController);
	}

	private void setProxyOfBean(Object proxy,
			AbstractBeanField websocketController) {
		System.out.println("setting bean of " + websocketController.getBean());
		websocketController.getField().setAccessible(true);
		try {
			System.out.println("setting private field");
			websocketController.getField().set(websocketController.getBean(),
					proxy);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		websocketController.getField().setAccessible(false);
	}
}
